<template>
    <movable-area v-if="reload" class="slide-v" :class="`slide-v-${props.uuid}`">
        <view v-if="!props.isShowTime" class="tip-v">{{ slideStatus === 'moving' ? timeText : successText }}</view>
        <view v-else-if="props.isShowTime && slideStatus === 'moving'" class="tip-v">
            <view>
                {{ `${props.text} (已接单` }}
            </view>
            <view style="color: #fd9224">{{ computedTime(counter) }}</view>
            <view>{{ ')' }}</view>
        </view>
        <view v-else class="tip-v">
            {{ successText }}
        </view>
        <view class="slide-bg" :style="`width:${old.slideWidth}px`"></view>

        <movable-view
            class="slide-block"
            :direction="slideStatus === 'moving' ? 'horizontal' : 'none'"
            :x="slideWidth"
            :animation="false"
            @change="onChange"
            @touchend="onTouchEnd"
        >
            <u-icon
                class="icon"
                :name="slideStatus === 'moving' ? 'arrow-right-double' : 'checkbox-mark'"
                size="30"
                :color="slideStatus === 'moving' ? '#fff' : '#42b983'"
            ></u-icon>
        </movable-view>
    </movable-area>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, PropType, computed, onBeforeUnmount } from 'vue'
import computedTime from '@/utils/computedTime'

const initNumber = 0.000000000000001
const props = defineProps({
    text: {
        type: String,
        default: '请按住滑块，拖动至最右边',
    },
    successText: {
        type: String,
        default: '操作成功',
    },
    uuid: {
        type: String as PropType<Long>,
        default: '',
    },
    isShowTime: {
        type: Boolean,
        default: false,
    },
    time: {
        type: Number,
        default: 0,
    },
})

const counter = ref(props.time)
const timer = ref<NodeJS.Timeout>()
const start = () => {
    timer.value = setInterval(() => {
        counter.value++
    }, 1000)
}
if (props.isShowTime) start()

onBeforeUnmount(() => {
    if (timer.value) {
        clearInterval(timer.value)
    }
})

const timeText = computed(() => {
    if (props.isShowTime) {
        return `${props.text} (已接单${computedTime(counter.value)})`
    } else {
        return props.text
    }
})

const reload = ref(true)
const emit = defineEmits(['success'])

const old = ref({
    slideWidth: 0,
})
const slideWidth = ref(initNumber)
const slideTotalWidth = ref(0)
const slideBlockWidth = ref(0)
const enum SlideStatus {
    moving = 'moving',
    success = 'success',
}
const slideStatus = ref<keyof typeof SlideStatus>('moving')

type ChangeEvent = {
    detail: {
        x: number
        y: number
        source: keyof typeof Source
    }
}
const enum Source {
    'touch' = 'touch', // 拖动
    'touch-out-of-bounds' = 'touch-out-of-bounds', // 超出移动范围
    'outOfBounds' = 'out-of-bounds', // 超出移动范围后的回弹
    'friction' = 'friction', // 惯性
    '' = '', // setData
}

function onChange(e: ChangeEvent) {
    old.value.slideWidth = e.detail.x
    // 多给 2px 的误差
    if (slideTotalWidth.value > 0 && e.detail.x >= slideTotalWidth.value - slideBlockWidth.value - 2) {
        slideSuccess()
    }
}
const onTouchEnd = async () => {
    if (slideStatus.value === 'moving') {
        console.log('老', old.value.slideWidth)
        console.log('总', slideTotalWidth.value, slideTotalWidth.value / 2)
        slideWidth.value = initNumber
        await nextTick()
        setTimeout(async () => {
            console.log(old.value.slideWidth >= slideTotalWidth.value / 2)
            if (old.value.slideWidth >= slideTotalWidth.value / 2) {
                old.value.slideWidth = slideTotalWidth.value
                slideWidth.value = slideTotalWidth.value
                slideSuccess()
            } else {
                old.value.slideWidth = 0
                slideWidth.value = 0
            }
            console.log(slideWidth.value)
        }, 200)
    }
}
const getSlideWidth = () => {
    const query = uni.createSelectorQuery()
    const selectClass = `.slide-v.slide-v-${props.uuid}`
    query.select(selectClass).boundingClientRect()
    query.exec((res) => {
        slideTotalWidth.value = res[0].width
    })
}

const getBlockWidth = () => {
    const query = uni.createSelectorQuery()
    query.select('.slide-block').boundingClientRect()
    query.exec((res) => {
        slideBlockWidth.value = res[0].width
    })
}

const slideSuccess = async () => {
    slideStatus.value = 'success'
    emit('success')
}

onMounted(() => {
    getWidth()
})

const getWidth = async () => {
    await nextTick()
    getSlideWidth()
    getBlockWidth()
}

const init = async () => {
    reload.value = false
    slideWidth.value = initNumber
    old.value.slideWidth = 0
    slideStatus.value = 'moving'
    await nextTick()
    setTimeout(async () => {
        reload.value = true
        await nextTick()
        getWidth()
    }, 100)
}
defineExpose({
    init,
})
</script>

<style lang="scss" scoped>
.slide-v {
    width: 0;
    flex: 1;
    background: rgb(85, 92, 253);
    height: 100rpx;
    border-radius: 16rpx;
    position: relative;
    margin-left: 15rpx;
    .tip-v {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #fff;
        z-index: 0;
        font-size: 26rpx;
        text-wrap: nowrap;
        // 文字不换行
        white-space: nowrap;
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
    }
    .slide-bg {
        height: 100%;
        border-top-left-radius: 16rpx;
        border-bottom-left-radius: 16rpx;
        background-color: #fff;
        z-index: 100;
        transform: scale(1.023);
    }

    .slide-block {
        background-color: transparent;
        height: 100%;
        width: 104rpx;
        position: relative;
        box-sizing: border-box;
        .icon {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 100;
            animation: slider 1s linear infinite;
        }
        @keyframes slider {
            from {
                transform: translate(-50%, -50%) scale(0.8);
            }
            to {
                transform: translate(calc(-50% + 20rpx), -50%) scale(1.1);
            }
        }
    }
}
</style>
